open Base
open OUnit2
open Helper

module Example_core = struct
  type ctx = Ctx
  type spine = Spine
  let in_container Spine Ctx = Ctx

  type ('s, 'e) atom =
    | Simple: string -> (unit, string) atom

  let init_atom (type s e) ~(cb: e -> unit) ~ctx:_
    : (s, e) atom -> (s -> unit) Staged.t =
    function
    | Simple(name) -> begin
        logf "init(%s)" name;
        Staged.stage (fun () -> cb name)
      end
end

;;
run_test_tt_main @@
test_list
  [
    ts (module Int)
      ["math1", 3 + 4, 7;
       "math2", 8 * 2, 16];
    ts (module IntOption)
      ["opt1", Some(3), Some(1 + 2);
       "opt2", None,    None];
    t_log "hello_world" ["hello";"world"]
      (fun () -> log "hello"; logf "w%sld" "or");

    (***********************)
    (* components          *)

    "Components">:::begin
      let module C = Ax.Make_components(Example_core) in
      let a = C.atom (Example_core.Simple("A")) ~init:() in
      let b = C.atom (Example_core.Simple("B")) ~init:() in
      let ab = C.container ~s:Spine [a; b] in
      [
        "mount">:::[
          t_log "atom" ["init(A)"] (fun () -> C.mount Ctx a);
          t_log "container" ["init(A)"; "init(B)"] (fun () -> C.mount Ctx ab);
        ];
      ]
    end;

  ]
